package com.rytong.tools.offstore;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.http.HttpStatus;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;

import com.rytong.tools.crypto.AESCipher;
import com.rytong.tools.crypto.HMac;
import com.rytong.tools.httpconnect.HttpManager;
import com.rytong.tools.httpconnect.WaitDialog;
import com.rytong.tools.httpconnect.WaitDialog.Task;
import com.rytong.tools.utils.CacheBitmapUtils;
import com.rytong.tools.utils.EventHandler;
import com.rytong.tools.utils.LPToastUtil;
import com.rytong.tools.utils.Utils;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.os.Message;
import android.text.TextUtils;
import android.util.DisplayMetrics;

public class OffStoreDownload {
	static public String FILEROOT;
	final static public String PLUGROOT = "plug-in-resources/"; // 插件包资源
	final static public String OFFLINEROOT = "offline-resources/"; // 离线下载资源
	final static public String WRITEROOT = "write-resources/";
	private final String PLUGRESOURCES = "plug_in_resources.db";
	private final String OFFLINERESOURCES = "offline_resources.db";
	private Activity activity_;
	// 是否必须更新(-1:不更新，0：不强制更新,1：强制更新
	private String mustupate_;

	// 需要更新资源列表
	private HashMap<String, String> resourceMap_;
	// 列表path和rev(SHA1的hash)
	private HashMap<String, HashMap<String, String>> serverMap_;
	private HashMap<String, Boolean> alreadyDownload_;
	private byte[] serverString_;
	// 离线更新接口
	public static final String RESOURCE_UPDATE = "/ota_s/resource_update?";
	private int downloadNum_;
	/**
	 * 下载离线资源次数
	 */
	//private int downloadCount_;
	
	public OffStoreDownload(Activity activity) {
		activity_ = activity;
		alreadyDownload_ = new HashMap<String, Boolean>();
		downloadNum_ = 1;// 重复下载一次即可
		OffStoreDB.OFFLINEDB = new OffStoreDB(activity, OFFLINERESOURCES);
		OffStoreDB.PLUGDB = new OffStoreDB(activity, PLUGRESOURCES);
	}

	/**
	 * 步骤1：发送请求：平台类型、屏幕分辨率、server.desc（不存在则为空）
	 * @param serverUrl
	 */
	public void downloadOfflineResource(final String serverUrl) {
		//downloadCount_ = 0;
		// 手机平台
		final String platform = Utils.getConfigStringFormAsset(activity_, "offstoreplatform");
		// 分辨率
		DisplayMetrics dm = new DisplayMetrics();
		activity_.getWindowManager().getDefaultDisplay().getMetrics(dm);
		final String screenResolution = String.valueOf(dm.widthPixels) + "*" + String.valueOf(dm.heightPixels);
		try {
			// 本地离线文件client.desc(不为空则发送) 需要解密
			Object object = OffStoreDB.OFFLINEDB.find("client.desc");
			String descTemp = null;
			if (object != null) {
				descTemp = new String(AESCipher.decrypt((byte[]) object, AESCipher.customerKey_, AESCipher.customerIv_));
			}
			final String client_desc = descTemp;
			Timer timer_ = new Timer();
			timer_.schedule(new TimerTask() {
				@Override
				public void run() {
					HttpManager hm = new HttpManager(activity_);
					String uri = serverUrl.concat(RESOURCE_UPDATE);
					StringBuffer buf = new StringBuffer();
					buf.append("desc=");
					if (client_desc != null){
						buf.append(Utils.escapeURIComponent(client_desc));						
					}
					buf.append("&platform=").append(platform).append("&resolution=").append(screenResolution);
					try {
						String body = buf.toString();
						Utils.printOutToConsole("OffStoreDownload===uncodebody===:" + body);
						Utils.printOutToConsole("OffStoreDownload===uri===:" + uri);
						// 离线下载走加解密
						body = AESCipher.encrypt(body, AESCipher.clientKey_, AESCipher.clientIv_);
						String reply = (String) hm.sendPostRequest(uri, body, HttpManager.MIME_JSON, null);
					
						Utils.printOutToConsole("OffStoreDownload===reply===:"+reply);
						Utils.printOutToConsole("OffStoreDownload===codebody===:"+body);
						if(!TextUtils.isEmpty(reply)){
							reply = AESCipher.decrypt(reply, AESCipher.serverKey_, AESCipher.serverIv_);
							if (reply == null || ((String) reply).trim().startsWith("{\"message\":")) {
								// 返回失败信息
								final Builder ad = new AlertDialog.Builder(activity_);
								ad.setTitle("提示")
								  .setMessage("离线下载失败!")
								  .setCancelable(false)
								  .setNegativeButton("确定",
										new DialogInterface.OnClickListener() {
											public void onClick(
													DialogInterface dialog,
													int which) {
												callClientGotoAct(true);
											}
										}
								  );
								if (!activity_.isFinishing()) {
									activity_.runOnUiThread(new Runnable() {
										@Override
										public void run() {
											ad.show();
										}
									});
									return;
								}
							} else {// 返回成功信息
								// 步骤2：读取返回的download.desc和server.desc
								parseResponse(reply);
							}
						}
					} catch (Exception e) {
						Utils.printException(e);
					}
				}
			}, 0);
		} catch (Exception e) {
			Utils.printException(e);
		}
	}

	/**
	 * 步骤2：读取返回的download.desc和server.desc
	 * @param serverUpdate
	 */
	protected void parseResponse(Object serverUpdate) {
		if (serverUpdate instanceof String)
			parseJSON((String) serverUpdate);
	}

	/**
	 * 先判断是否需要强制更新，如果不是强制更新，则提醒用户更新
	 * @param serverResponse
	 */
	private void parseJSON(String serverResponse) {
		try {
			Utils.printOutToConsole("OffStoreDownload===offstore data===: " + serverResponse);
			final JSONObject obj = new JSONObject(serverResponse);
			// 是否必须更新
			mustupate_ = obj.getString("mustupdate");
			if (null == mustupate_)
				return;
			if (mustupate_.equalsIgnoreCase("0")) {
				// 提示更新离线资源
				//startsplashcontrolbar();
				downloadResource(obj);
				/*final Builder ad = new AlertDialog.Builder(activity_);
				ad.setTitle("提示").setMessage("您有离线资源需要更新")
						.setPositiveButton("确定",
								new DialogInterface.OnClickListener() {

									public void onClick(DialogInterface dialog,
											int which) {
										// TODO Auto-generated method stub
									}

								}).setNegativeButton("退出",
								new DialogInterface.OnClickListener() {

									public void onClick(DialogInterface dialog,
											int which) {
										callClientGotoAct(true);
									}

				});
				if (!activity_.isFinishing()) {
					activity_.runOnUiThread(new Runnable() {

						@Override
						public void run() {
							// TODO Auto-generated method stub
							ad.show();
						}

					});
				}*/
			} else if (mustupate_.equalsIgnoreCase("-1")) {
				//无更新
				//没有要更新的离线资源文件也认为是更新完成
				LPToastUtil.isUpdateOffline = true;
				offlineflash();
				/*activity_.runOnUiThread(new Runnable() {

					@Override
					public void run() {
						startsplashcontrolbar() ; //开始splash进度条
						callClientGotoAct(false);
					}
				});*/
			} else if (mustupate_.equalsIgnoreCase("1")) {
				// 强制更新
				//startsplashcontrolbar(); 
				downloadResource(obj);
			}
		} catch (JSONException e) {
			Utils.printException(e);
		}
	}

	/**
	 * 下载离线资源
	 * @param obj
	 */
	private void downloadResource(final JSONObject obj) {
		// TODO Auto-generated method stub
		WaitDialog wd = new WaitDialog();
		wd.addBgTask( new Task(0) {
			@Override
			public void run(WaitDialog dlg) throws Exception {
				parseJSONIndeed(obj);
				// 根据路径下载每一个resource
				downloadResourceByPath();
				// 删除过期资源
				deleteExpireFile();
			}

			public void onSuccess(WaitDialog dlg) {
				super.onSuccess(dlg);
				//离线资源下载成功
				LPToastUtil.isUpdateOffline = true;
				offlineflash();
				/*final Builder ad = new AlertDialog.Builder(activity_);
				ad.setTitle("提示")
						.setMessage("离线资源已更新")
						.setCancelable(false)
						.setNegativeButton("确定",
								new DialogInterface.OnClickListener() {

									public void onClick(DialogInterface dialog,
											int which) {
										callClientGotoAct(false);
									}

								});
				if (!activity_.isFinishing()) {
					activity_.runOnUiThread(new Runnable() {

						public void run() {
							// TODO Auto-generated method stub
							ad.show();
						}

					});
				}*/
			}
			public void onFailure(WaitDialog dlg){
				super.onFailure(dlg);
				/**
				 * 离线资源下载失败
				 */
				LPToastUtil.isUpdateOffline = false;
			}
		});
	}

	// 解析JSON---步骤3：解析download.desc
	private void parseJSONIndeed(JSONObject obj) {
		// TODO Auto-generated method stub
		// download.desc
		try {
			resourceMap_ = new HashMap<String, String>();
			serverMap_ = new HashMap<String, HashMap<String, String>>();
			String key = "";
			if (obj.has("download")) {
				JSONObject downObject;
				downObject = obj.getJSONObject("download");
				Iterator itDown = downObject.keys();
				String value = "";
				while (itDown.hasNext()) {
					key = itDown.next().toString();
					value = downObject.getString(key);
					// 未下载，未更新标志为false;更新后修改标志位
					alreadyDownload_.put(key, false);
					resourceMap_.put(key, value);
				}
			}

			if (obj.has("server")) {
				// server.desc
				JSONObject serverObject = obj.getJSONObject("server");
				serverString_ = serverObject.toString().getBytes();
				Iterator itServer = serverObject.keys();
				key = "";
				JSONObject jsonValue;
				String path;
				String rev;
				String desc;
				while (itServer.hasNext()) {
					key = itServer.next().toString();
					jsonValue = serverObject.getJSONObject(key);

					HashMap<String, String> params = new HashMap<String, String>();
					if (jsonValue.has("path")) {
						path = jsonValue.getString("path");
						params.put("path", path);
					}
					if (jsonValue.has("rev")) {
						rev = jsonValue.getString("rev");
						params.put("rev", rev);
					}
					if (jsonValue.has("desc")) {
						desc = jsonValue.getString("desc");
						params.put("desc", desc);
					}

					serverMap_.put(key, params);
				}
			}

		} catch (JSONException e) {
			// TODO Auto-generated catch block
			Utils.printException(e);
		}
	}

	// 步骤5：根据download.desc下载列表建立任务队列task-list
	public void downloadResourceByPath() {
		try {
			//下载次数超过2两次不再下载
//			downloadCount_++;
//			if(downloadCount_ > 2 ){
//				return;
//			}
			String fileName = null, filePath = null, shaFile = null, serverFileName = null, serverPath = null, serverRev = null;
			byte[] fileString = null;
			if (resourceMap_ == null)
				return;

			if (!resourceMap_.isEmpty()) {
				Iterator it = resourceMap_.keySet().iterator();
				HashMap<String, String> params;
				while (it.hasNext()) {
					downloadNum_ = 1;
					fileName = it.next().toString().trim();
					filePath = resourceMap_.get(fileName);
					if (checkDownload(fileName)) {
						// 已经下载则返回
						return;
					} else {
						// 下载每个文件
						fileString = downloadPerResource(filePath,false);
						File file = new File(fileName);
						if (Utils.getMIMEType(file).equalsIgnoreCase("zip")) {
							// 如果数据是压缩的则应进行解压操作
							unZip(fileName, new ByteArrayInputStream(fileString));
						}
						file = null;
						// 计算文件SHA1值
						if (fileString != null) {
							byte[] temp = HMac.SHA1(fileString);
							shaFile = HMac.byteArrayToHexString(temp);
						}
						// 查找第二个Map中含有第一个Map的key
						if (serverMap_.containsKey(fileName)) {
							params = serverMap_.get(fileName);
							serverPath = params.get("path");
							serverRev = params.get("rev");
							Utils.LogD("serverPath:", serverPath);
							Utils.LogD("serverRev:", serverRev);
						}
						// 步骤6：每一个资源文件下载完毕后计算资源文件的SHA1值，并与server.desc记录的SHA1值进行比较递归)
						comparedRedownload(fileName, shaFile, filePath, fileString, serverRev);
					}
				}
			}

			if (checkAllDownload()) {
				// 下载10:下载完毕后存储server.desc文件
				OffStoreDB.OFFLINEDB.deleteToDB("client.desc");

				String clientDesc = createDescStr();
				byte[] serverDesc = AESCipher.encrypt(clientDesc.getBytes(), AESCipher.customerKey_, AESCipher.customerIv_);
				OffStoreDB.saveToDb(OffStoreDB.OFFLINEDB, "client.desc", serverDesc);
			} else {
				downloadResourceByPath();
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			Utils.printException(e);
		}
	}

	/**
	 * 解压资源文件
	 * @param fileName
	 * @param input
	 */
	private void unZip(String fileName, InputStream input) {
		// TODO Auto-generated method stub
		ZipInputStream zis = new ZipInputStream(new BufferedInputStream(input));
		try {
			ZipEntry ze;
			String root = PLUGROOT;
			Utils.saveFile(root, null);
			while ((ze = zis.getNextEntry()) != null) {
				ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
				byte[] buffer = new byte[1024];
				int count;
				while ((count = zis.read(buffer)) != -1) {
					baos.write(buffer, 0, count);
				}
				String zpFileName = ze.getName().trim();
				byte[] bytes = baos.toByteArray();

				if (zpFileName.endsWith("/")) {// 路径
					Utils.saveFile(root.concat(zpFileName), null);
				} else {
					// 计算文件SHA1值
					String zpShaFile = null;
					if (bytes != null) {
						byte[] temp = HMac.SHA1(bytes);
						if (temp != null) {
							zpShaFile = HMac.byteArrayToHexString(temp);
						}
					}
					// 服务器传输的hash值
					String servierDesc = null;
					if (serverMap_.containsKey(fileName)) {
						HashMap<String, String> params = serverMap_.get(fileName);
						servierDesc = params.get("desc");
					}
					if (servierDesc != null) {
						JSONObject obj = new JSONObject(servierDesc);
						Iterator<String> iterator = obj.keys();
						String zpServeRev = null;
						while (iterator.hasNext()) {
							String key = iterator.next();
							if (key.equalsIgnoreCase(zpFileName)) {
								zpServeRev = obj.getString(key);
							}
						}
						if (zpServeRev != null) {
							boolean noModify = comparedSHA1(zpFileName, zpShaFile, zpServeRev);
							if (noModify) {// 如果验证通过
								// 保存文件
								Utils.saveFile(root.concat(zpFileName), bytes);
								// 数据库保存文件hash值
								OffStoreDB.PLUGDB.deleteToDB(zpFileName);
								Utils.LogD("zpServeName:",zpFileName);
								Utils.LogD("zpServeRev:",zpServeRev);
								byte[] serverRev = AESCipher.encrypt(zpServeRev.getBytes(), AESCipher.customerKey_, AESCipher.customerIv_);
								OffStoreDB.saveToDb(OffStoreDB.PLUGDB, zpFileName, serverRev);
							} else {
								// 验证失败

							}
						}
					}
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			Utils.printException(e);
		} catch (Exception e) {
			Utils.printException(e);
		} finally {
			try {
				if (null != zis)
					zis.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				Utils.printException(e);
			}
		}

	}

	/**
	 * @param fileName
	 *            客户端文件名
	 * @param shaFile
	 *            客户端计算出的SHA1
	 * @param filePath
	 *            客户端下载文件的路径
	 * @param fileString
	 *            客户端下载文件后的字节数�?
	 * @param serverFileName
	 *            服务器端文件名字
	 * @param serverRev
	 *            服务器端SHA1
	 */
	private void comparedRedownload(String fileName, String shaFile, String filePath, byte[] fileString, String serverRev) {
		try {
			boolean noModify = comparedSHA1(fileName, shaFile, serverRev);
			if (noModify) {
				File file = new File(fileName);
				if (!Utils.getMIMEType(file).equalsIgnoreCase("zip")) {
					// 步骤7:验证资源文件的正确性后，以name为key存储资源文件
					// 下载完的文件保存到数据库
					if (serverMap_.containsKey(fileName)) {
						HashMap<String, String> params = serverMap_.get(fileName);
						String path = params.get("path");
						if (path != null && !path.equals("")) {
							if (!path.endsWith("/")) {
								path = path.concat("/");
							}
							Utils.saveFile(OFFLINEROOT.concat(path), null);
							Utils.saveFile(OFFLINEROOT.concat(path).concat(fileName), fileString);
							OffStoreDB.OFFLINEDB.deleteToDB(path.concat(fileName));
							Utils.LogD("offlineroot+",OFFLINEROOT.concat(path).concat(fileName));
							byte[] serRev = AESCipher.encrypt(serverRev.getBytes(), AESCipher.customerKey_, AESCipher.customerIv_);
							OffStoreDB.saveToDb(OffStoreDB.OFFLINEDB, path.concat(fileName), serRev);
						}
					}
				}
				// 步骤8：更新download.desc的下载状态标记，标记为已下载
				// 保存到数据库后修改已下载的标志位
				alreadyDownload_.put(fileName, true);
			} else {
				Utils.printOutToConsole("-----------资源文件校验失败:"+fileName+"-------------");
				if (downloadNum_-- > 0) {
					// 重新下载每个文件
					fileString = downloadPerResource(filePath,true);
					File file = new File(fileName);
					if (Utils.getMIMEType(file).equalsIgnoreCase("zip")) {
						// 如果数据是压缩的则应进行解压操作
						unZip(fileName, new ByteArrayInputStream(fileString));
					}
					file = null;
					// 重新计算文件SHA1值
					if (fileString != null) {
						byte[] disg = HMac.SHA1(fileString);
						if (disg != null) {
							shaFile = HMac.byteArrayToHexString(disg);// disg.toString();
							Utils.LogD("shaFile+",shaFile);
						}
					}
					comparedRedownload(fileName, shaFile, filePath, fileString, serverRev);
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			Utils.printException(e);
		}
	}

	// 判断文件名为fileName的文件是否下载过
	private boolean checkDownload(String fileName) {
		if (alreadyDownload_ != null) {
			return alreadyDownload_.get(fileName);
		}
		return false;
	}

	// 判断所有的文件是否下载
	private boolean checkAllDownload() {
		if (alreadyDownload_ != null) {
			if (!alreadyDownload_.isEmpty()) {
				for (Map.Entry<String, Boolean> entry : alreadyDownload_.entrySet()) {
					boolean entryDownload = entry.getValue();
					// 如果有值为false,即没有下载完，所有的都为true，才为全部下载完
					if (!entryDownload)
						return false;
				}
			}
			// 全部下载完成
			return true;
		}
		return false;
	}

	// 比较下栽文件的SHA1和server.desc
	private boolean comparedSHA1(String fileName, String shaFile, String serverSHA1) {
		if (fileName != null && shaFile != null & serverSHA1 != null) {
			if (shaFile.equalsIgnoreCase(serverSHA1)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 下载文件列表中的每一个文件
	 * 如果是重新下载的话，就走另一种下载方式
	 * @param filePath
	 * @param isRedownload
	 * @return
	 */
	private byte[] downloadPerResource(String filePath,boolean isRedownload) {
		ByteArrayOutputStream fileBuffer = new ByteArrayOutputStream(1024);
		byte[] fileBytes = null;
		
		HttpURLConnection conn = null;
		InputStream inputStream = null;
		try {
			if(!isRedownload){
				HttpManager hm = new HttpManager(activity_);
				hm.read(filePath, fileBuffer, null);
				fileBytes = fileBuffer.toByteArray();				
			}else{
				URL url = new URL(filePath);
				conn = (HttpURLConnection) url.openConnection();
				conn.setConnectTimeout(5*1000);
				if (conn.getResponseCode() == HttpStatus.SC_OK) {
					inputStream = conn.getInputStream();
					if(null != inputStream){
						fileBytes = CacheBitmapUtils.readStream(inputStream);
					}
				}
			}
		} catch (Exception e) {
			Utils.printException(e);
		} catch (OutOfMemoryError oe) {
			Utils.printOutToConsole(oe);
		} finally {
			if (null != fileBuffer){
				try {
					fileBuffer.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					Utils.printException(e);
				}
				fileBuffer = null;
			}
			
			if (null != inputStream) {
				try {
					inputStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				inputStream = null;
			}
			if(null != conn){
				conn.disconnect();				
			}
		}
		return fileBytes;
	}

	public boolean getFirstLogin() {
		File file = new File(activity_.getFilesDir(), OffStoreDB.OFFLINEDB.DATABASE_NAME);
		return file.exists();
	}

	public static void setRootPath() {
		// TODO Auto-generated method stub
		FILEROOT = Utils.getActivity().getFilesDir().getPath().concat("/");
		// FILEROOT = "/";
	}

	/**
	 * 删除过期资源
	 * 
	 * 插件资源、离线资源
	 * */
	private void deleteExpireFile() {
		try {
			boolean deleteFile;

			// 离线资源
			List<Object> offlineList = OffStoreDB.OFFLINEDB.getListByColumnName();
			String offFilePath = null;
			for (Object obj : offlineList) {
				if (obj instanceof String) {
					offFilePath = (String) obj;
				}
				if (offFilePath != null && !offFilePath.equalsIgnoreCase("client.desc")) {
					deleteFile = true;
					Set<String> set = serverMap_.keySet();
					Iterator<String> iterator = set.iterator();
					while (iterator.hasNext()) {
						String key = iterator.next();
						String path = serverMap_.get(key).get("path");
						if (!path.endsWith("/")) {
							path = path.concat("/");
						}
						if (path.concat(key).equalsIgnoreCase(offFilePath)) {
							deleteFile = false;
						}
					}

					if (deleteFile) {
						// 如果服务器没有此记录则删除
						OffStoreDB.OFFLINEDB.deleteToDB(offFilePath);
						// 删除本地存储的文件
						File file = new File(OffStoreDownload.FILEROOT.concat(OFFLINEROOT).concat(offFilePath));
						if (file.exists()) {
							file.delete();
						}
					}
				}
			}

			Utils.deleteEmptyPath(new File(OffStoreDownload.FILEROOT.concat(OFFLINEROOT)));

			// 插件资源
			List<Object> pluginList = OffStoreDB.PLUGDB.getListByColumnName();
			String filePath = null;
			for (Object object : pluginList) {
				deleteFile = true;
				if (object instanceof String) {
					filePath = (String) object;
				}
				if (filePath != null) {
					Set<String> set = serverMap_.keySet();
					Iterator<String> itServer = set.iterator();
					while (itServer.hasNext()) {
						String fileNameTemp = itServer.next();

						if (fileNameTemp.endsWith(".zip")) {
							String zipdesc = serverMap_.get(fileNameTemp).get("desc");
							if (zipdesc != null) {
								JSONObject obj = new JSONObject(zipdesc);
								Iterator<String> itDesc = obj.keys();
								while (itDesc.hasNext()) {
									String descFilePath = itDesc.next();
									if (filePath.equals(descFilePath)) {
										deleteFile = false;
									}
								}
							}
						}
					}
					if (deleteFile) {
						// 如果服务器没有此记录则删除
						OffStoreDB.PLUGDB.deleteToDB(filePath);
						// 删除本地存储的文件
						File file = new File(OffStoreDownload.FILEROOT.concat(PLUGROOT).concat(filePath));
						if (file.exists()) {
							file.delete();
						}
					}
				}
			}

			Utils.deleteEmptyPath(new File(OffStoreDownload.FILEROOT.concat(PLUGROOT)));
		} catch (Exception e) {
			Utils.printException(e);
		}
	}

	/**
	 * 组装本地client.desc 内容
	 * */
	private String createDescStr() {
		JSONStringer json = new JSONStringer();
		try {

			json.object();

			JSONObject object = new JSONObject();

			Set<String> set = serverMap_.keySet();
			Iterator<String> itServer = set.iterator();
			while (itServer.hasNext()) {

				String key = itServer.next();

				JSONObject tempObj = new JSONObject();
				String rev = serverMap_.get(key).get("rev");
				String path = serverMap_.get(key).get("path");
				tempObj.put("rev", rev);
				tempObj.put("path", path);

				object.put(key, tempObj);
			}
			json.key("resources").value(object).endObject();

		} catch (Exception e) {
			Utils.printException(e);
		}
		return json.toString();
	}

	public void callClientGotoAct(boolean doQuit) {
		EventHandler uh = EventHandler.getUtHandler();
		Message msg = new Message();
		if (doQuit) {
			msg.what = EventHandler.MSG_KILL_PROCESS;
		} else {
			msg.what = EventHandler.MSG_GOTOALLOWACT;
		}
		uh.eventHandler.sendMessage(msg);
	}
/**
 * OFFline下载后刷新页面
 */
	public void offlineflash() {
		EventHandler uh = EventHandler.getUtHandler();
		Message msg = new Message();
		msg.what = EventHandler.OFFLINE_FLASH;
		uh.eventHandler.sendMessage(msg);
	}
	/**
	 * 原有的进度条更新
	 */
	public void startsplashcontrolbar(){
		EventHandler uhdlert = EventHandler.getUtHandler();
		Message msg = new Message();
		msg.what = EventHandler.MSG_SPLASH_STARTCONTROLBAR;
		uhdlert.eventHandler.sendMessage(msg);
	}
	
	/**
	 * 离线资源文件，将离线资源的zip文件保存到本地并生成client.desc
	 * 
	 * @param zipName
	 */
	public void unzipLocalFile(String zipName){
		//生成服务器的server列表，以便创建client.desc
		if(null == serverMap_){
			serverMap_ = new HashMap<String, HashMap<String,String>>();
		}
		ZipInputStream zis = null;
		
		try {
			InputStream is = activity_.getAssets().open(zipName);
			zis = new ZipInputStream(new BufferedInputStream(is));
			
			ZipEntry ze;
			while ((ze = zis.getNextEntry()) != null) {
				ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
				byte[] buffer = new byte[1024];
				int count;
				while ((count = zis.read(buffer)) != -1) {
					baos.write(buffer, 0, count);
				}
				String zpFileName = ze.getName().trim();
				byte[] bytes = baos.toByteArray();
				if (zpFileName.endsWith("/")) {
					//创建文件夹
					Utils.saveFile(zpFileName, null);
				} else {
					// 保存文件
					Utils.saveFile(zpFileName, bytes);
					
					HashMap<String, String> params = new HashMap<String,String>();
					String fileName = zpFileName.substring(zpFileName.lastIndexOf("/")+1);
					String filePath = zpFileName.substring(OFFLINEROOT.length(),zpFileName.lastIndexOf("/"));
					// 计算文件SHA1值
					String shaFile = null;
					if (bytes != null) {
						byte[] temp = HMac.SHA1(bytes);
						if (temp != null) {
							shaFile = HMac.byteArrayToHexString(temp);
						}
					}
					params.put("path", filePath);
					params.put("rev", shaFile);
					//params.put("desc", null);
					serverMap_.put(fileName, params);
					
					Utils.LogD("zpLocalName:",fileName);
					Utils.LogD("zpLocalPath:",filePath);
					Utils.LogD("zpLocalRec:",shaFile);
					Utils.LogD("file-------->",filePath.concat("/").concat(fileName));

					// 数据库保存文件hash值
					OffStoreDB.OFFLINEDB.deleteToDB(filePath.concat(fileName));
					byte[] clientRev = AESCipher.encrypt(shaFile.getBytes(), AESCipher.customerKey_, AESCipher.customerIv_);
					OffStoreDB.saveToDb(OffStoreDB.OFFLINEDB, filePath.concat("/").concat(fileName), clientRev);
				}
			}
			
			//生成并保存到client.desc
			OffStoreDB.OFFLINEDB.deleteToDB("client.desc");
			String clientDesc = createDescStr();
			byte[] serverDesc = AESCipher.encrypt(clientDesc.getBytes(), AESCipher.customerKey_, AESCipher.customerIv_);
			OffStoreDB.saveToDb(OffStoreDB.OFFLINEDB, "client.desc", serverDesc);
		} catch (Exception e) {
			Utils.printException(e);
		} finally {
			try {
				if (null != zis)
					zis.close();
			} catch (IOException e) {
				Utils.printException(e);
			}
		}
	}
	
	/**
	 * 删除所有的本地资源文件，然后再解压
	 */
//	public File fileTemp = new File(FILEROOT+OFFLINEROOT);
//	public void deleteAllLocalFile(File file){
////		if(!file.exists() || file.isFile()){
////			return;
////		}
////		File[] files = file.listFiles();
////		for(File temp : files){
////			if(temp.isDirectory()){
////				deleteAllLocalFile(temp);
////			}else{
////				temp.delete();
////			}
////		}
//	}
}
